package com.seven.monior;

import java.sql.Date;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.TrafficStats;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.seven.monior.AppInfo.Global;
import com.seven.monior.AppInfo.SortType;
import com.seven.monior.TaskInfo.TaskDetail;
import com.seven.monior.TaskInfo.TaskInfo;
import com.seven.monior.TaskInfo.TaskItemAdapter;

public class Tasks extends Activity {
	private TextView tv_device_network_info;
	private Button btn_reset;
	private ListView task_list;

	private ActivityManager am = Global.am;
	private ArrayList<TaskInfo> mTaskInfos;
	private TaskItemAdapter adapter;
	private UpdateUIReceiver updateUIReceiver;

	private Handler handler;
	private ProgressDialog progressDialog;

	private SortType sortType = SortType.Sort_By_Bytes;
	private boolean showZeroApps = false;

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// showList();
		if (progressDialog == null) {
			progressDialog = new ProgressDialog(this);
		}
		progressDialog.setMessage("Loading...");
		progressDialog.setIndeterminate(true);
		progressDialog.show();

		setContentView(R.layout.tasks_layout);

		// databaseHelper = new DatabaseHelper(this);
		adapter = new TaskItemAdapter(this);
		adapter.setShowRandT(true);
		adapter.setShowCPU(false);
		mTaskInfos = new ArrayList<TaskInfo>();

		// mTaskInfos = Global.taskInfoList;

		// initListFromDB(databaseHelper);
		adapter.AddData(mTaskInfos);
		task_list = (ListView) findViewById(R.id.task_list);
		task_list.setAdapter(adapter);
		this.registerForContextMenu(task_list);
		task_list.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				// TODO Auto-generated method stub

				TaskInfo tInfo = (TaskInfo) mTaskInfos.get(position);
				// if (tInfo.getApplicationLabelList().size() <= 1) {
				// String pkgName = tInfo.getPkgName();
				// // showInstalledAppDetails(pkgName);
				//
				//
				//
				// } else {
				// view.showContextMenu();
				// // Log.d("click", "click");
				// }
				//
				Intent i = new Intent();
				i.setClass(parent.getContext(), TaskDetail.class);
				i.putExtra("uid", tInfo.getUID());
				startActivity(i);

				// Intent intent = new Intent(Intent.ACTION_VIEW);
				// intent.setClassName("com.android.settings",
				// "com.android.settings.InstalledAppDetails");
				// intent.putExtra("pkg", pkgName);
				//
				// startActivity(intent);
			}
		});

	}

	public void onResume() {
		super.onResume();
		if (mTaskInfos.size() <= 0) {
			progressDialog.setMessage("Loading...");
			progressDialog.setIndeterminate(true);
			progressDialog.show();
			mTaskInfos = Global.getTaskInfos(false, showZeroApps, sortType);
		}

		updateUIReceiver = new UpdateUIReceiver();
		IntentFilter filter = new IntentFilter();// 创建IntentFilter对象
		filter.addAction(Global.ACTION_UPDATE_UI);
		registerReceiver(updateUIReceiver, filter);// 注册Broadcast Receiver

		Looper looper = Looper.getMainLooper();
		handler = new MessageHandler(looper);
		// handler.post(doRefreshList);
		handler.sendEmptyMessage(0);

	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		// TODO Auto-generated method stub
		AdapterContextMenuInfo info;

		try {
			// Casts the incoming data object into the type for
			// AdapterView objects.
			info = (AdapterView.AdapterContextMenuInfo) menuInfo;
		} catch (ClassCastException e) {
			// If the menu object can't be cast, logs an error.
			Log.e("MENU ERROR", "bad menuInfo", e);
			return;
		}

		TaskInfo tInfo = mTaskInfos.get(info.position);

		menu.setHeaderTitle(tInfo.getApplicationLabel());
		for (int i = 0; i < tInfo.getApplicationLabelList().size(); i++) {
			menu.add(0, i, i, tInfo.getApplicationLabelList().get(i));

		}
	}

	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info;

		try {
			// Casts the incoming data object into the type for
			// AdapterView objects.
			info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
		} catch (ClassCastException e) {
			// If the menu object can't be cast, logs an error.
			Log.e("MENU ERROR", "bad menuInfo", e);
			return false;
		}

		TaskInfo tInfo = mTaskInfos.get(info.position);
		ArrayList<String> pkgList = tInfo.getPkgNameList();
		String sPkgName = pkgList.get(item.getItemId());
		showInstalledAppDetails(sPkgName);

		// Intent i = new Intent();
		// i.setClass(this, TaskDetail.class);
		// i.putExtra("uid", tInfo.getUID());
		// startActivity(i);

		return false;
	}

	private class UpdateUIReceiver extends BroadcastReceiver {// 继承自BroadcastReceiver的子类
		@Override
		public void onReceive(Context context, Intent intent) {// 重写onReceive方法

			if (handler != null) {
				mTaskInfos = Global.getTaskInfos(false, showZeroApps, sortType);
				handler.sendEmptyMessage(0);
			}
			// showList();

		}
	}

	@Override
	protected void onStart() {// 重写onStart方法

		super.onStart();
	}

	@Override
	protected void onStop() {// 重写onStop方法

		super.onStop();
	}

	protected void onPause() {
		unregisterReceiver(updateUIReceiver);// 取消注册Broadcast Receiver

		handler.removeCallbacks(doUpdateUI);
		handler.removeMessages(1);
		super.onPause();
	}

	private Runnable doRefreshList = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub

			// Intent intent = new Intent(Global.ACTION_UPDATE_TASKLIST);
			// sendBroadcast(intent);
			RefreshList();
		}
	};

	private void RefreshList() {

		List<RunningAppProcessInfo> rInfos = am.getRunningAppProcesses();
		for (int j = 0; j < rInfos.size(); j++) {
			RunningAppProcessInfo rInfo = rInfos.get(j);
			boolean bCatch = false;
			for (int i = 0; i < mTaskInfos.size(); i++) {
				TaskInfo tInfo = mTaskInfos.get(i);
				if (tInfo.getUID() == rInfo.uid) {
					bCatch = true;
					Long lMobile_Rx = tInfo.m_lMobile_Rx;
					Long lMobile_last_Rx = tInfo.m_lMobile_last_Rx;
					Long lMobile_Tx = tInfo.m_lMobile_Tx;
					Long lMobile_last_Tx = tInfo.m_lMobile_last_Tx;

					Long lMobile_now_Rx;
					Long lMobile_now_Tx;
					Long lTotal_Rx = tInfo.m_lTotal_Rx;
					Long lTotal_last_Rx = tInfo.m_lTotal_last_Rx;
					Long lTotal_Tx = tInfo.m_lTotal_Tx;
					Long lTotal_last_Tx = tInfo.m_lTotal_last_Tx;

					Long lTotal_now_Rx = TrafficStats.getUidRxBytes(rInfo.uid);

					Long lTotal_now_Tx = TrafficStats.getUidTxBytes(rInfo.uid);

					if (wifi_IsConnected()) {
						lMobile_now_Rx = 0L;
						lMobile_now_Tx = 0L;
					} else {
						lMobile_now_Rx = lTotal_now_Rx;
						lMobile_now_Tx = lTotal_now_Tx;
					}
					if (lMobile_now_Rx - lMobile_last_Rx >= 0
							&& lMobile_last_Rx > 0) {
						lMobile_Rx += lMobile_now_Rx - lMobile_last_Rx;
						tInfo.m_lMobile_Rx = lMobile_Rx;
					}
					lMobile_last_Rx = lMobile_now_Rx;
					tInfo.m_lMobile_last_Rx = lMobile_last_Rx;

					if (lMobile_now_Tx - lMobile_last_Tx >= 0
							&& lMobile_last_Tx > 0) {
						lMobile_Tx += lMobile_now_Tx - lMobile_last_Tx;
						tInfo.m_lMobile_Tx = lMobile_Tx;
					}
					lMobile_last_Tx = lMobile_now_Tx;
					tInfo.m_lMobile_last_Tx = lMobile_last_Tx;

					if (lTotal_now_Rx - lTotal_last_Rx >= 0
							&& lTotal_last_Rx > 0) {
						lTotal_Rx += lTotal_now_Rx - lTotal_last_Rx;
						tInfo.m_lTotal_Rx = lTotal_Rx;
					}
					lTotal_last_Rx = lTotal_now_Rx;
					tInfo.m_lTotal_last_Rx = lTotal_last_Rx;

					if (lTotal_now_Tx - lTotal_last_Tx >= 0
							&& lTotal_last_Tx > 0) {
						lTotal_Tx += lTotal_now_Tx - lTotal_last_Tx;
						tInfo.m_lTotal_Tx = lTotal_Tx;
					}
					lTotal_last_Tx = lTotal_now_Tx;
					tInfo.m_lTotal_last_Tx = lTotal_last_Tx;

				}
			}
			if (!bCatch) {
				TaskInfo tInfo = new TaskInfo(rInfo.uid, true, 0L, 0L, 0L, 0L);
				mTaskInfos.add(tInfo);
				Log.d("ADD NEW TASKINFO", "ADD NEW TASKINFO");
			}
		}

		Comparator<TaskInfo> sortByName = new Comparator<TaskInfo>() {

			@Override
			public int compare(TaskInfo rInfo1, TaskInfo rInfo2) {
				// TODO Auto-generated method stub
				String name1 = rInfo1.getProcessName().toLowerCase();
				String name2 = rInfo2.getProcessName().toLowerCase();

				return name1.compareTo(name2);
			}
		};

		Comparator<TaskInfo> sortByBytes = new Comparator<TaskInfo>() {

			@Override
			public int compare(TaskInfo rInfo1, TaskInfo rInfo2) {
				// TODO Auto-generated method stub
				Long byte1 = rInfo1.getMobile_RxandTx();
				Long byte2 = rInfo2.getMobile_RxandTx();

				return byte2.compareTo(byte1);
			}
		};

		Collections.sort(mTaskInfos, sortByBytes);

		handler.sendEmptyMessage(0);

		// handler.post(doUpdateUI);
	}

	private Runnable doUpdateUI = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			UpdateUI();

		}
	};

	private void UpdateUI() {

		adapter.AddData(mTaskInfos);
		adapter.notifyDataSetChanged();

		tv_device_network_info = (TextView) findViewById(R.id.tv_device_network_info);
		btn_reset = (Button) findViewById(R.id.btn_reset);

		String strCurrentMobileTotal = "Mobile_Total_Rx: "
				+ Global.Total_Mobile_Rx + " Bytes \n";
		strCurrentMobileTotal += "Mobile_Total_Tx: " + Global.Total_Mobile_Tx
				+ " Bytes \n";

		// String strCurrentMobileTotal = "Mobile_Total_Rx: "
		// + Global.Total_Mobile_Rx + " Bts / " + Global.Total_Mobile_Rp
		// + " Pkts \n";
		// strCurrentMobileTotal += "Mobile_Total_Tx: " + Global.Total_Mobile_Tx
		// + " Bts / " + Global.Total_Mobile_Tp + " Pkts \n";

		// strCurrentMobileTotal += "All_Total_Rx: " + Global.Total_All_Rx +
		// " / "
		// + Global.Total_All_Rp + "\n";
		// strCurrentMobileTotal += "All_Total_Tx: " + Global.Total_All_Tx +
		// " / "
		// + Global.Total_All_Tp + "\n";

		strCurrentMobileTotal += "Since: "
				+ Global.SINCE_TIMESTAMP.toLocaleString();

		tv_device_network_info.setText(strCurrentMobileTotal);

		btn_reset.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				Intent intent = new Intent(Global.ACTION_RESET);
				sendBroadcast(intent);

				progressDialog.setMessage("Reseting...");
				progressDialog.setIndeterminate(true);
				progressDialog.show();

				// mTaskInfos.clear();
				Global.resetMobileBytes();

				long currentTime = System.currentTimeMillis();
				Global.SINCE_TIMESTAMP = new Date(currentTime);
				Global.Total_Mobile_Rx = 0L;
				Global.Total_Mobile_Tx = 0L;
				// Global.last_Mobile_Rx = 0L;
				// Global.last_Mobile_Tx = 0L;

				Global.Total_Mobile_Rp = 0L;
				Global.Total_Mobile_Tp = 0L;
				// Global.last_Mobile_Rp = 0L;
				// Global.last_Mobile_Tp = 0L;

				// Global.Total_All_Rx = 0L;
				// Global.Total_All_Tx = 0L;
				// Global.last_All_Rx = 0L;
				// Global.last_All_Tx = 0L;
				//
				// Global.Total_All_Rp = 0L;
				// Global.Total_All_Tp = 0L;
				// Global.last_All_Rp = 0L;
				// Global.last_All_Tp = 0L;

				SharedPreferences sPreferences = getSharedPreferences(
						Global.PREFS, Activity.MODE_PRIVATE);
				SharedPreferences.Editor editor = sPreferences.edit();
				editor.putLong("since_time", currentTime);
				editor.putLong("total_mobile_rx", Global.Total_Mobile_Rx);
				editor.putLong("total_mobile_tx", Global.Total_Mobile_Tx);
				editor.putLong("last_mobile_rx", Global.last_Mobile_Rx);
				editor.putLong("last_mobile_tx", Global.last_Mobile_Tx);
				editor.commit();
				mTaskInfos = new ArrayList<TaskInfo>();
				handler.sendEmptyMessage(0);
			}
		});

		// handler.sendEmptyMessage(0);
		Log.d("UPDATE UI", "UI UPDATED!");

	}

	private class MessageHandler extends Handler {

		public MessageHandler(Looper looper) {

			super(looper);

		}

		@Override
		public void handleMessage(Message msg) {
			UpdateUI();
			if (MonitorService.InitialFinished && progressDialog.isShowing()) {
				progressDialog.dismiss();
			}
			super.handleMessage(msg);

			// handler.postDelayed(doRefreshList, 2000L);

		}

	}

	private boolean wifi_IsConnected() {
		try {
			if (Global.cm != null) {

				// 获取网络连接管理的对象
				NetworkInfo info = Global.cm.getActiveNetworkInfo();

				if (info != null && info.isConnected()) {
					int nType = info.getType();
					if (nType == ConnectivityManager.TYPE_WIFI
							|| nType == ConnectivityManager.TYPE_WIMAX) {
						// 判断当前网络是否已经连接
						if (info.getState() == NetworkInfo.State.CONNECTED) {
							return true;
						}
					}
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			Log.v("get connection state error", e.toString());
		}
		return false;
	}

	private static final String SCHEME = "package";
	/**
	 * 调用系统InstalledAppDetails界面所需的Extra名称(用于Android 2.1及之前版本)
	 */
	private static final String APP_PKG_NAME_21 = "com.android.settings.ApplicationPkgName";
	/**
	 * 调用系统InstalledAppDetails界面所需的Extra名称(用于Android 2.2)
	 */
	private static final String APP_PKG_NAME_22 = "pkg";
	/**
	 * InstalledAppDetails所在包名
	 */
	private static final String APP_DETAILS_PACKAGE_NAME = "com.android.settings";
	/**
	 * InstalledAppDetails类名
	 */
	private static final String APP_DETAILS_CLASS_NAME = "com.android.settings.InstalledAppDetails";

	private static final String APP_DETAILS_ACTION_23 = "android.settings.APPLICATION_DETAILS_SETTINGS";

	/**
	 * 调用系统InstalledAppDetails界面显示已安装应用程序的详细信息。 对于Android 2.3（Api Level
	 * 9）以上，使用SDK提供的接口； 2.3以下，使用非公开的接口（查看InstalledAppDetails源码）。
	 * 
	 * @param context
	 * 
	 * @param packageName
	 *            应用程序的包名
	 */
	public void showInstalledAppDetails(String packageName) {
		Intent intent = new Intent();
		final int apiLevel = Build.VERSION.SDK_INT;
		if (apiLevel >= 9) { // 2.3（ApiLevel 9）以上，使用SDK提供的接口
			intent.setAction(APP_DETAILS_ACTION_23);
			Uri uri = Uri.fromParts(SCHEME, packageName, null);
			intent.setData(uri);
		} else { // 2.3以下，使用非公开的接口（查看InstalledAppDetails源码）
			// 2.2和2.1中，InstalledAppDetails使用的APP_PKG_NAME不同。
			final String appPkgName = (apiLevel == 8 ? APP_PKG_NAME_22
					: APP_PKG_NAME_21);
			intent.setAction(Intent.ACTION_VIEW);
			intent.setClassName(APP_DETAILS_PACKAGE_NAME,
					APP_DETAILS_CLASS_NAME);
			intent.putExtra(appPkgName, packageName);
		}
		startActivity(intent);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		menu.add(0, 0, 0, "Sort by Bytes");
		menu.add(0, 1, 1, "Sort by Name");
		menu.add(0, 2, 2, "Sort by Cputime");
		if (showZeroApps) {
			menu.add(0, 3, 3, "Remove non-data Apps");
		} else {
			menu.add(0, 3, 3, "Show non-data Apps");
		}
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub

		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// TODO Auto-generated method stub
		switch (item.getItemId()) {
		case 0:
			if (sortType != SortType.Sort_By_Bytes) {
				sortType = SortType.Sort_By_Bytes;
				adapter.setShowRandT(true);
				adapter.setShowCPU(false);
				// Global.SortList(mTaskInfos, sortType);
				mTaskInfos = Global.getTaskInfos(false, showZeroApps, sortType);
			}
			break;
		case 1:
			if (sortType != SortType.Sort_By_Name) {
				sortType = SortType.Sort_By_Name;
				adapter.setShowRandT(true);
				adapter.setShowCPU(false);
				// Global.SortList(mTaskInfos, sortType);
				mTaskInfos = Global.getTaskInfos(false, showZeroApps, sortType);
			}
			break;
		case 2:
			if (sortType != SortType.Sort_By_Cputime) {
				sortType = SortType.Sort_By_Cputime;
				adapter.setShowRandT(false);
				adapter.setShowCPU(true);
				// Global.SortList(mTaskInfos, sortType);
				mTaskInfos = Global.getTaskInfos(false, showZeroApps, sortType);
			}
			break;
		case 3:
			showZeroApps = !showZeroApps;
			mTaskInfos = Global.getTaskInfos(false, showZeroApps, sortType);
			if (showZeroApps) {
				item.setTitle("Remove non-data Apps");
			} else {
				item.setTitle("Show non-data Apps");
			}
			break;
		}
		handler.sendEmptyMessage(0);
		return super.onOptionsItemSelected(item);
	}

}
